package workers;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.SwingWorker;

import model.Software;
import workerUIs.StepFrame;

import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

public abstract class AbstractStepSwingWorker extends
		SwingWorker<Software, Void> {
	
	protected Logger logger = Logger.getLogger(AbstractStepSwingWorker.class.getCanonicalName());
	
	protected Software software;
	protected final StepFrame frame;
	protected final String inputQueueName;
	protected final String outputQueueName;

	public AbstractStepSwingWorker(final StepFrame frame, final String inputQueueName, final String outputQueueName) {
		this.frame = frame;
		this.inputQueueName = inputQueueName;
		this.outputQueueName = outputQueueName;
	}

	public StepFrame getFrame() {
		return frame;
	}
	
	@Override
	protected Software doInBackground() throws Exception {
		try {
			final MQQueueManager qm = new MQQueueManager(IMQConstants.MQM_NAME);
			this.software = getMessage(qm, inputQueueName);
			if (this.software != null) {
				doStep(this.software);
				putMessage(qm, outputQueueName, this.software);			
			}
			qm.disconnect();
			return this.software;
		} catch (Exception e) {
			logger.log(Level.SEVERE, "Exception when executing step: " + getClass().getName() + ": " + e.getMessage());
		}
		return null;
	}
	
	@Override
	protected void done() {
		String previousStepString = this.frame.getTextArea().getText();
		if (this.software != null) {
			this.frame.getTextArea().setText(previousStepString + "\n--------------\n" + this.software.toString());
		} else {
			this.frame.getTextArea().setText(previousStepString + "\n--------------\n" + "Software NULL!");
		}
	}
	
	protected Software getMessage(MQQueueManager qm, String queueName) throws Exception {
		if (queueName == null || queueName.isEmpty()) return null;
		MQQueue queue = qm.accessQueue(queueName, IMQConstants.OPEN_OPTIONS);
		MQMessage msg = new MQMessage();
		queue.get(msg, new MQGetMessageOptions());
		Software readObject = (Software) msg.readObject();
		queue.close();
		return readObject;
	}
	
	protected void putMessage(MQQueueManager qm, String queueName, Software software) throws Exception {
		if (queueName == null || queueName.isEmpty()) return;
		MQQueue queue = qm.accessQueue(queueName, IMQConstants.OPEN_OPTIONS);
		MQMessage msg = new MQMessage();
		msg.writeObject(software);
		queue.put(msg, new MQPutMessageOptions());
		queue.close();
	}
	
	protected abstract void doStep(Software software);
	
}
